package han.chensing.latos.common.level.content.timeLine.valuebook;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import han.chensing.latos.common.level.util.MathUtil;

public class ValueBookPage implements Serializable {
    @Serial
    private static final long serialVersionUID = -2909287131384896778L;

    private float fromTime,toTime;
    private final List<ValueBookEntry> entries =new ArrayList<>();
    private int cachedEntryPosition=0;

    public float getValue(float relativeTime){
        ValueBookEntry currentEntry = getCurrentEntry(relativeTime);
        return currentEntry.getValue(relativeTime - currentEntry.getRelativeFromTime());
    }

    private ValueBookEntry getCurrentEntry(float relativeTime) {
        while(true) {
            if (!MathUtil.isInRange(0,cachedEntryPosition, entries.size()-1)){
                cachedEntryPosition= (int) MathUtil.range(0,cachedEntryPosition, entries.size()-1);
                return entries.get(cachedEntryPosition);
            }
            ValueBookEntry valueBookEntry = entries.get(cachedEntryPosition);
            float relativeFromTime = valueBookEntry.getRelativeFromTime();
            float relativeToTime = valueBookEntry.getRelativeToTime();
            int range = MathUtil.judgeRange(relativeFromTime, relativeTime, relativeToTime);
            if (range==0){
                return valueBookEntry;
            }else if (range==-1){
                cachedEntryPosition++;
            }else if (range==1){
                cachedEntryPosition--;
            }
        }
    }

    public void connectEntries(){
        if (entries.isEmpty()) return;
        ValueBookEntry lastEntry=entries.get(0);
        for (int i = 1; i < entries.size(); i++) {
            ValueBookEntry thisEntry = entries.get(i);
            lastEntry.setRelativeToTime(thisEntry.getRelativeFromTime());
            lastEntry.updateDuration();
            lastEntry=thisEntry;
        }
        lastEntry.setRelativeToTime(toTime-fromTime);
        lastEntry.updateDuration();
    }

    public List<ValueBookEntry> getEntries() {
        return entries;
    }

    public float getFromTime() {
        return fromTime;
    }

    public void setFromTime(float fromTime) {
        this.fromTime = fromTime;
    }

    public float getToTime() {
        return toTime;
    }

    public void setToTime(float toTime) {
        this.toTime = toTime;
    }
}
